<?php

class Novel_model extends CI_Model {

    function __construct() {
        parent::__construct();
    }

    /**
     * Model to get all manga available
     * @return type 
     */
    function getNovel_all() {
        $query = $this->db->order_by("name", "asc")->get('novel');

        $arr = array();
        foreach ($query->result() as $row) {
            $row->cats = $this->getNovelCategory($row->id);
            $arr[] = $row;
        }
        return $arr;
    }
    
    function getNovel_count() {
        return $this->db->count_all('novel');
    }
    
    /**
     * Model to get all manga by category Id
     * @return type 
     */
    function getNovel_byCate($catId) {
        $sql = "SELECT n.* FROM novel n, relationship r WHERE n.id = r.oid AND r.cid=" . $catId;
        $query = $this->db->query($sql);
        $arr = array();
        foreach ($query->result() as $row) {
            $arr[] = $row;
        }
        return $arr;
    }

    /**
     * Add new manga
     * @param type $arr array information of manga to add
     * @return type 
     */
    function addNovel($arr) {
        $cover = $arr['cover'];
        $newCover = './' . str_replace('tmp/', '', $cover);
        if($cover && !file_exists($newCover)) {
            $cover = str_replace('resource/tmp/', '/', $cover);
            copy('./' . $arr['cover'], $newCover);
            chmod($newCover, 0777);
        }
        $data = array(
            'name' => $arr['name'],
            'oname' => $arr['oname'],
            'slug' => slug($arr['name']),
            'author' => $arr['author'],
            'translator' => $arr['translator'],
            'description' => $arr['description'],
            'status' => $arr['status'],
            'cover' => $cover,
            'created' => REQUEST_TIME,
            'update' => 0
        );
        $result = $this->db->insert('novel', $data);
        $novelId = $this->db->insert_id();
        $this->updateCategoryRelationShip($novelId, $arr['cats']);
        return $novelId;
    }

    /**
     * Edit manga infor
     * @param type $arr array information of manga to edit
     * @return type 
     */
    function editNovel($arr) {
        $cover = $arr['cover'];
        if($cover) {
            $copyPath = './' . str_replace('tmp/', '', $cover);
            copy('./' . $arr['cover'], $copyPath);
            chmod($copyPath, 0777);
            $cover = str_replace('resource/tmp/', '/', $cover);
        }
        $data = array(
            'name' => $arr['name'],
            'oname' => $arr['oname'],
            'slug' => slug($arr['name']),
            'author' => $arr['author'],
            'translator' => $arr['translator'],
            'description' => $arr['description'],
            'status' => $arr['status'],
            'cover' => $cover,
            'update' => REQUEST_TIME
        );

        $this->db->where('id', $arr['id']);
        $result = $this->db->update('novel', $data);
        $this->updateCategoryRelationShip($arr['id'], $arr['cats']);
        return $result;
    }

    /**
     * Remove a manga out of Database
     * @param type $id id of manga
     * @return type 
     */
    function removeNovel($id) {
        $this->mongo_db->delete('novel', array('novelId' => $id));
        $this->removeNovelCategory($id);
        return $this->db->delete('novel', array('id' => $id));
        
    }
    
    function getNovelCategory($novelId) {
        $query =  $this->db->get_where('relationship', array('oid' => $novelId));
        $arr = array();
        foreach ($query->result() as $row) {
            $arr[] = $row->cid;
        }
        return $arr;    
    }
    
    function updateCategoryRelationShip($novelId, $cats) {
        $this->removeNovelCategory($novelId);
        $data = array();
        foreach ($cats as $cat) {
            $data[] = array('oid' => $novelId, 'cid' => $cat);
        }
        return $this->db->insert_batch('relationship', $data);
    }
    
    function removeNovelCategory($novelId) {
        return $this->db->delete('relationship', array('oid' => $novelId));
    }

    /**
     * Validate manga infor before add to DB 
     * @param type $arr array data of manga 
     * @return type 
     */
    function addNovel_validate($arr) {
        extract($arr);

        $err = 0;
        $msg = array();
        // validate username
        if (!$this->validateName($name)) {
            $err = -1;
            $msg['name'] = 'Novel Name invalid';
        }

        //check manga other name exit
        if (!$this->validateName($oname)) {
            $err = -1;
            $msg['oname'] = 'Novel Other name invalid';
        }

        //check manga author name
        if (!$this->validateName($author)) {
            $err = -1;
            $msg['author'] = 'Author name invalid';
        }

        //check manga translator name
        if (!$this->validateName($translator)) {
            $err = -1;
            $msg['translator'] = 'Translator name invalid';
        }

        // validate Description
        if (!$this->validateDescription($desc)) {
            $msg['desc'] = 'Description invalid';
            $err = -1;
        }
        //check manga name exit
        $id = isset($id) ? $id : 0;
        if ($this->checkNameExist($name, $id)) {
            $msg['name'] = 'Novel name exist';
            $err = -3;
        }
        return array('err' => $err, 'msg' => $msg);
    }

    function uploadCover() {
        $cfg['upload_path'] = COVER_TMP_DIR;
        $cfg['allowed_types'] = 'gif|jpg|png';
        $cfg['max_size'] = 1024 * 5;
        $cfg['encrypt_name'] = true;
        $cfg['max_width'] = '2048';
        $cfg['max_height'] = '1536';

        $this->upload->initialize($cfg);
        $err = array();
        if (!$this->upload->do_upload('file')) {
            $err['err'] = -1;
            $err['msg'] = 'Upload Failure';
            $err['data'] = $this->upload->display_errors();
        } else {
            $err['err'] = 0;
            $err['msg'] = 'Success.';
            $err['data'] = $this->upload->data();
            chmod($err['data']['full_path'], 0777);
            $this->resizeCover($err['data']['full_path']);
            chmod($err['data']['full_path'], 0777);
        }
        return $err;
    }

    private function resizeCover($full_path) {
        $rz['image_library'] = 'gd2';
        $rz['source_image'] = $full_path;
        $rz['width'] = COVER_WIDTH;
        $rz['height'] = COVER_HEIGHT;
        
        $this->image_lib->initialize($rz);
        $this->image_lib->resize();
    }

    function getNovel_by_id($id) {
        $novel = $this->getNovelInfo_by_id($id);
        $chapter = $this->mongo_db->where('novelId', $id)->order_by(array("chapter" => "asc"))->get('novel');
        $novel->chapter = $chapter;
        function sortChapter($a, $b) {
            if ($a['chapter'] == $b['chapter']) {
                usort($novel->chapter, 'sortChapter');
                return 0;
            }
            return ($a['chapter'] < $b['chapter']) ? -1 : 1;
        }
        usort($novel->chapter, 'sortChapter');
        return $novel;
    }
    
    function getNovelInfo_by_id($id) {
        $novel = $this->db->get_where('novel', array('id' => $id))->row();
        $novel->cats = $this->getNovelCategory($id);
        return $novel;
    }

    function getNovel_slug_by_id($novelId) {
        return $this->db->select('slug')->get_where('novel', array('id' => $novelId))->row()->slug;
    }

    private function validateName($name) {
        return strlen($name) <= 100;
    }

    private function validateDescription($desc) {
        return mb_strlen($desc) <= 2000;
    }

    private function checkNameExist($name, $id = 0) {
        $query_u = $this->db->get_where('novel', array('name' => $name));
        if ($id != 0 && $query_u->num_rows > 0) {
            $result = $query_u->row();
            return $id != $result->id;
        } else
            return $query_u->num_rows > 0;
    }

    /**
     * Make new chapter for a manga
     * 
     * @param type $mangaId: manga Id 
     * @param type $chapterId: chapter Id
     * @return type
     */
    function addNewChapter($novelId, $chapterId) {
        $data = array(
            'novelId' => $novelId,
            'chapter' => $chapterId,
            'title' => '',
            'content' => '',
            'update' => REQUEST_TIME,
            'created' => REQUEST_TIME
        );
        return $this->mongo_db->insert('novel', $data);
    }
    
    /**
     * Validate chapter infor 
     * @param type $arr array data of manga 
     * @return type 
     */
    function getChapter_validate($arr) {
        extract($arr);
        $err = 0;
        $msg = array();
        //check manga id exit
        $novelId = isset($novelId) ? $novelId : 0;
        if (!$this->checkNovelIdExist($novelId)) {
            $msg['novelId'] = 'Novel id not exist';
            $err = -1;
        }
        return array('err' => $err, 'msg' => $msg);
    }
    
    /**
     * Check a manga is exist or not
     * 
     * @param type $id
     * @return type 
     */
    private function checkNovelIdExist($id = 0) {
        $query_u = $this->db->get_where('novel', array('id' => $id));
        return $query_u->num_rows > 0;
    }
    
    /**
     * Get chapter detail of a manga
     * 
     * @param type $mangaId: manga Id
     * @param type $chapterId: chapter Id
     * @return type 
     */
    function getChapter_by_chapterId($novelId, $chapterId) {
        $data = $this->mongo_db->where(array('novelId' => $novelId, 'chapter' => $chapterId))->get('novel');
        return $data;
    }
    
    /**
     * Delete a chapter and all image files
     * @param type $slug
     * @param type $chapterId
     * @return type
     */
    function deleteChapter_by_id($slug, $chapterId, $novelId) {
        return $this->mongo_db->where(array('novelId' => $novelId, 'chapter' => $chapterId))->delete('novel');
    }
    
    /**
     * Update image list to a chapter
     * 
     * @param type $arr
     * @return type 
     */
    function updateChapter_by_chapterId($arr) {
        $data = array('content' => $arr['content'], 'status' => $arr['status'], 'title' => $arr['title'], 'update' => REQUEST_TIME);
        $result = $this->mongo_db->where(array('novelId' => $arr['novelId'], 'chapter' => $arr['chapterId']))->set($data)->update('novel');
        return $result;
    }
}

?>
